//配置模块：负责读取客户端和服务器端的配置文件，设置默认值
//read_client_config：读取客户端配置文件 client.conf，设置服务器 IP 和端口。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "utils.h"

/**
 *  读取客户端配置文件，设置客户端连接服务器所需的配置信息。
 * 
 * 该函数会尝试读取客户端配置文件，若文件不存在，则使用默认配置。
 * 配置文件中可配置服务器 IP 地址和端口号，若配置文件中未提供相应配置，也会使用默认值。
 * 
 *  config 指向 ClientConfig 结构体的指针，用于存储读取到的配置信息。
 */
void read_client_config(ClientConfig *config) {
    // 设置默认值：若配置文件不存在或缺少某些配置项，将使用这些默认值
    // 将服务器 IP 地址默认设置为本地回环地址
    strcpy(config->server_ip, "127.0.0.1");
    // 将服务器端口号默认设置为 9999
    config->server_port = 9999;
    
    // 尝试以只读模式打开配置文件
    FILE *file = fopen(CONFIG_FILE, "r");
    // 检查文件是否成功打开
    if (!file) {
        // 若文件未找到，打印提示信息并使用默认设置
        printf("未找到配置文件 %s，使用默认设置\n", CONFIG_FILE);
        return;
    }
    
    // 用于存储从文件中读取的每一行内容
    char line[256];
    // 逐行读取配置文件，直到文件结束
   while (fgets(line, sizeof(line), file)) {
        trim_string(line); // 去除行首和行尾的空白符
         // 跳过空行
        if (strlen(line)== 0) {   
            continue;
        }
        // 跳过注释行和空行
        if(line[0] == '#' || line[0] == '\0') { 
            continue;
        }
        // 移除行内注释，防止出现解析后为9999 #服务端口的情况
        //shtrchr查找#字符
        char *comment = strchr(line, '#');
        if (comment) {
            *comment = '\0';
        }

       
        //解析键值对
        //从配置文件读取的单行内容里分割出键值对
        // 使用strchr在line里查找 = 首次出现的位置
        //sep：指向 line 字符串中首次出现 = 字符位置的指针。
        //若 line 中不存在 = 字符，sep 为 NULL。
        //if判断sep 是否为 NULL。
        //若不为 NULL，意味着 line 中存在 = 字符，可进行键值对分割操作。
        //若为NULL，则打印提示信息并跳过当前行。
        char *sep = strchr(line, '=');
        if (sep) {
            // 分割键值对
            //将 sep 指针指向的字符（即 =）替换成字符串结束符 '\0'。
            //这样，line 字符串就被截断为 = 之前的部分，作为键。
            //line 字符串中 = 字符之后的部分（即 sep + 1），则作为值。
            //调用 trim_string 函数去除键和值两端的空白符。
            *sep = '\0'; 
            char *key = line;
            char *value = sep + 1;
            // 检查值是否为空
            if (*value == '\0') {
                printf("配置项值为空: %s\n", key);
                continue;
            }
            // 修剪键和值两端的空格
            trim_string(key);
            trim_string(value);

            // 检查键是否为 "ServerIP"
            if (strcmp(key, "ServerIP") == 0) {
                // 若为 "ServerIP"，将解析出的值复制到配置结构体的 server_ip 字段
                strcpy(config->server_ip, value);
            }
            // 检查键是否为 "ServerPort"
            else if (strcmp(key, "ServerPort") == 0) {
                // 若为 "ServerPort"，将解析出的值转换为整数并赋值给配置结构体的 server_port 字段
                config->server_port = atoi(value);
            }
            else {
                // 对未识别的配置项给出提示
                printf("未识别的配置项: %s = %s\n", key, value);
            }
        }
    }
    // 关闭已打开的配置文件
    fclose(file);
    return;
}

